package hu.mapro.jpa.model.client.domain;

import hu.mapro.jpa.model.domain.client.AutoBeans.Factory;
import hu.mapro.jpa.model.domain.client.AutoBeans.FetchPlan;
import hu.mapro.jpa.model.domain.client.AutoBeans.FetchProperty;
import hu.mapro.model.meta.FieldChain;

import java.util.Collection;

@SuppressWarnings("rawtypes")
public class FetchPlanCreator<T> {

	public static <T> FetchPlan createFetchPlan(
			Factory factory,
			Collection<? extends FieldChain<T, ?, ?>> chains
	) {
		return new FetchPlanCreator<T>(factory, chains).create();
	}
	
	public FetchPlanCreator(
			Factory factory,
			Collection<? extends FieldChain<T, ?, ?>> chains
	) {
		super();
		this.factory = factory;
		this.chains = chains;
	}

	Factory factory;
	Collection<? extends FieldChain<T, ?, ?>> chains;
	
	public FetchPlan create() {
		FetchPlan root = factory.fetchPlan();
		
		for (FieldChain chain : chains) {
			processChain(root, chain);
		}
		
		return root;
	}

	private FetchPlan processChain(FetchPlan plan, FieldChain<?,?,?> chain) {
		if (chain.getRoot().isPresent()) {
			plan = processChain(plan, chain.getRoot().get());
		}
			
		for (FetchProperty fp : plan.getProperties()) {
			if (fp.getPropertyName().equals(chain.getField().getName())) {
				return fp.getFetchPlan();
			}
		}
		
		FetchProperty fp = factory.fetchProperty();
		
		fp.setPropertyName(chain.getField().getName());
		plan.getProperties().add(fp);
		
		FetchPlan p = factory.fetchPlan();
		fp.setFetchPlan(p);
		
		return p;
		
	}
	
}
